//
// CWmStreaming.h
//
/**
 ** Copyright (C) 2005 EnjoyView Inc., all rights reserved.
 **           Your View, Our Passion. Just Enjoy It!
 **
 **            http://spaces.msn.com/members/jemylu
 **
 **/

/*************************************************************************/

#ifndef __H_CWmStreaming__
#define __H_CWmStreaming__

class CWmStreaming : public IWMReaderCallback, public IWMReaderCallbackAdvanced
{
private:
	LONG		m_cRef;        // reference count
	HANDLE		mAsyncEvent;   // event handle
	HRESULT		mhrAsync;      // HRESULT during async operations
	BOOL		mIsEOF;        // TRUE if EOF is reached or we need to stop

	WCHAR		mSourceFile[MAX_PATH];	
	WCHAR		mPublishingPoint[MAX_PATH];	
	DWORD		mBroadcastPort;
	BOOL		mIsBroadcasting;
	BOOL		mIsPushing;
	QWORD		mSourceDuration;
	QWORD		mReaderTime;
	QWORD		mCurrentTime;

	// Miscellaneous interfaces that we need.
	IWMWriterAdvanced*		mIWriterAdvanced;
	IWMReaderAdvanced*		mIReaderAdvanced;
	IWMReader*				mIReader;
	IWMWriter*				mIWriter;
	IWMHeaderInfo*			mIReaderHeaderInfo;
	IWMHeaderInfo*			mIWriterHeaderInfo;
	IWMWriterNetworkSink*	mINetworkSink;
	IWMWriterPushSink*		mIPushSink;	
	IWMRegisterCallback*	mIPushSinkCallback;

public:
	CWmStreaming();
	~CWmStreaming();

	// --- IUnknown methods --- 
	HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid,
					/* [out] */ void __RPC_FAR *__RPC_FAR *ppvObject ); 
	ULONG STDMETHODCALLTYPE AddRef();
	ULONG STDMETHODCALLTYPE Release();

	// --- IWMReaderCallback methods --- 
	HRESULT STDMETHODCALLTYPE OnStatus( /* [in] */ WMT_STATUS Status,
										/* [in] */ HRESULT hr,
										/* [in] */ WMT_ATTR_DATATYPE dwType,
										/* [in] */ BYTE __RPC_FAR *pValue,
										/* [in] */ void __RPC_FAR *pvContext );

	HRESULT STDMETHODCALLTYPE OnSample( /* [in] */ DWORD dwOutputNum,
										/* [in] */ QWORD cnsSampleTime,
										/* [in] */ QWORD cnsSampleDuration,
										/* [in] */ DWORD dwFlags,
										/* [in] */ INSSBuffer __RPC_FAR *pSample,
										/* [in] */ void __RPC_FAR *pvContext );


	// --- IWMReaderCallbackAdvanced methods --- 
	virtual HRESULT STDMETHODCALLTYPE OnStreamSample( /* [in] */ WORD wStreamNum,
													  /* [in] */ QWORD cnsSampleTime,
													  /* [in] */ QWORD cnsSampleDuration,
													  /* [in] */ DWORD dwFlags,
													  /* [in] */ INSSBuffer __RPC_FAR * pSample,
													  /* [in] */ void __RPC_FAR * pvContext);

	virtual HRESULT STDMETHODCALLTYPE OnTime( /* [in] */ QWORD qwCurrentTime,
											  /* [in] */ void __RPC_FAR * pvContext);

	virtual HRESULT STDMETHODCALLTYPE OnStreamSelection( /* [in] */ WORD wStreamCount,
														 /* [in] */ WORD __RPC_FAR * pStreamNumbers,
														 /* [in] */ WMT_STREAM_SELECTION __RPC_FAR * pSelections,
														 /* [in] */ void __RPC_FAR * pvContext);

	virtual HRESULT STDMETHODCALLTYPE OnOutputPropsChanged( /* [in] */ DWORD dwOutputNum,
															/* [in] */ WM_MEDIA_TYPE __RPC_FAR * pMediaType,
															/* [in] */ void __RPC_FAR * pvContext );

	virtual HRESULT STDMETHODCALLTYPE AllocateForOutput( /* [in] */ DWORD dwOutputNum,
														 /* [in] */ DWORD cbBuffer,
														 /* [out] */ INSSBuffer __RPC_FAR *__RPC_FAR * ppBuffer,
														 /* [in] */ void __RPC_FAR * pvContext);

	virtual HRESULT STDMETHODCALLTYPE AllocateForStream( /* [in] */ WORD wStreamNum,
														 /* [in] */ DWORD cbBuffer,
														 /* [out] */ INSSBuffer __RPC_FAR *__RPC_FAR * ppBuffer,
														 /* [in] */ void __RPC_FAR * pvContext);

	HRESULT SetSource(CString& inSourceFile);
	HRESULT SetBroadcastPort(DWORD inPort, BOOL inEnable);
	HRESULT SetPushPublishingPoint(CString& inPoint, BOOL inEnable);
	HRESULT StartStreaming(void);
	HRESULT StopStreaming(void);

	long GetProgress(void);
	BOOL IsFinished(void);

private:
	void SetAsyncEvent(HRESULT hrAsync);
	void WaitForEvent(HANDLE hEvent, DWORD msMaxWaitTime = INFINITE);

	HRESULT CreateReaderAndWriter(void);
	HRESULT ConfigReaderAndWriter(void);
	HRESULT WriteHeader(const WCHAR * pwszName);
	HRESULT WriteScript(void);
};

#endif // __H_CWmStreaming__